home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / Triton / Source / classes / button.c next >
C/C++ Source or Header  |  1998-05-23  |  20KB  |  622 lines

  1. /*
  2.  *  OpenTriton -- A free release of the triton.library source code
  3.  *  Copyright (C) 1993-1998  Stefan Zeiger
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21.  
  22. /****** triton.library/class_Button ******
  23. *
  24. *   NAME    
  25. *    class_Button -- A BOOPSI button gadget
  26. *
  27. *   SUPERCLASS
  28. *    class_DisplayObject
  29. *
  30. *   SYNOPSIS
  31. *    TROB_Button
  32. *
  33. *   ATTRIBUTES
  34. *    <Default>        : ULONG buttontype
  35. *                       - TRBT_TEXT         : Text button (default)
  36. *                       - TRBT_GETFILE      : GetFile image button
  37. *                       - TRBT_GETDRAWER    : GetDrawer image button
  38. *                       - TRBT_GETENTRY     : GetEntry image button
  39. *                       [create]
  40. *    TRAT_Text        : STRPTR label
  41. *                       [create]
  42. *    TRAT_Flags       : ULONG flags
  43. *                       - TRBU_RETURNOK     : Activated by <Return>
  44. *                       - TRBU_ESCOK        : Activated by <Esc>
  45. *                       - TRBU_SHIFTED      : Shifted shortcut only
  46. *                       - TRBU_UNSHIFTED    : Unshifted shortcut only
  47. *                       - TRBU_YRESIZE (V2) : When this flag is set, the
  48. *                                             button will be vertically
  49. *                                             resizeable. This is required
  50. *                                             because beginning with V2
  51. *                                             the height of objects which
  52. *                                             are normally using the
  53. *                                             button height can be
  54. *                                             modified in the prefs
  55. *                                             editor. Set this flags
  56. *                                             WHEREVER POSSIBLE in order
  57. *                                             to make buttons adopt to
  58. *                                             taller objects in the same
  59. *                                             horizontal group.
  60. *                       [create]
  61. *
  62. *   APPLICATION MESSAGES
  63. *    TRMS_ACTION is sent when a pressed down button is released.
  64. *
  65. *   NOTES
  66. *    Although image buttons don't display a text string you can
  67. *    still set one using the TRAT_Text attribute in order to create
  68. *    a shortcut for the button.
  69. *
  70. ******/
  71.  
  72.  
  73. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. //////////////////////////////////////////////////////////////////////////////////////// Include our stuff //
  75. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76.  
  77. #define TR_THIS_IS_TRITON
  78. #define TR_EXTERNAL_ONLY
  79.  
  80. #include <ctype.h>
  81. #include <dos.h>
  82. #include <utility/hooks.h>
  83. #include <clib/alib_protos.h>
  84. #include <libraries/triton.h>
  85. #include <clib/triton_protos.h>
  86. #include "/internal.h"
  87. #include "button.def"
  88. #include "/prefs/Triton.h"
  89.  
  90. extern VOID __asm TR_InternalDrawFrame(register __a0 struct TR_Project *project,
  91.                        register __a1 struct RastPort *rp, register __d1 UWORD left,
  92.                        register __d2 UWORD top, register __d3 UWORD width,
  93.                        register __d4 UWORD height, register __d0 UWORD type,
  94.                        register __d5 BOOL inverted);
  95.  
  96. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. ///////////////////////////////////////////////////////////////////////////////////////// Global variables //
  98. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99.  
  100. struct IClass *TRCL_BUTTON_BoopsiImage=NULL;
  101.  
  102.  
  103. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. //////////////////////////////////////////////////////////////////////////////////////// Private functions //
  105. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106.  
  107. struct IClass __inline *TRCL_BUTTON_InitBoopsiImage(void);
  108. ULONG __asm TRCL_BUTTON_DispatchBoopsiImage(register __a0 struct IClass *Class,
  109.                         register __a2 Object *Object, register __a1 Msg ObjMsg);
  110. void __inline TRCL_BUTTON_DrawBoopsiImage(struct Image *Image, struct impDraw *DrawMsg);
  111.  
  112.  
  113. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. ////////////////////////////////////////////////////////////////////////////////////////////// Object data //
  115. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116.  
  117. #define OBJECT (&(object->DO.O))
  118. #define DISPLAYOBJECT (&(object->DO))
  119. #define BUTTON object
  120.  
  121.  
  122. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. ////////////////////////////////////////////////////////////////////////////////////////////////// Methods //
  124. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125.  
  126. TR_METHOD(Button,NEW,NewData)
  127. {
  128.   LONG uspos;
  129.   STRPTR newtext;
  130.  
  131.   if(!TRDP_DisplayObject_NEW(object,messageid,data,metaclass->trc_SuperClass)) return NULL;
  132.   data->project->trp_IDCMPFlags|=IDCMP_GADGETUP;
  133.   BUTTON->BClass=TRCL_BUTTON_BoopsiImage;
  134.   DISPLAYOBJECT->MinHeight=(data->project->trp_PropFont->tf_YSize)+4;
  135.  
  136.   if(BUTTON->Text)
  137.     if((uspos=TR_FirstOccurance(data->project->trp_Underscore,BUTTON->Text)+1))
  138.       DISPLAYOBJECT->Shortcut=tolower(BUTTON->Text[uspos]);
  139.  
  140.   if(BUTTON->Type==TRBT_TEXT) /* Text button */
  141.     {
  142.       newtext=BUTTON->Text;
  143.       BUTTON->TextLength=TR_FirstOccurance(0,newtext)+1;
  144.       if(!(BUTTON->Text=(STRPTR)AllocVec(BUTTON->TextLength, MEMF_ANY))) return NULL;
  145.       CopyMem((APTR)newtext,(APTR)(BUTTON->Text),BUTTON->TextLength);
  146.       BUTTON->PixelTextLength=TR_TextWidth(data->project,(STRPTR)(BUTTON->Text),0);
  147.  
  148.       BUTTON->BorderHeight=TR_FrameBorderHeight(data->project,TRFT_ABSTRACT_BUTTON);
  149.       DISPLAYOBJECT->MinHeight+=(2*BUTTON->BorderHeight);
  150.       DISPLAYOBJECT->MinWidth=BUTTON->PixelTextLength+(data->project->trp_PropFont->tf_YSize*2)+4;
  151.       DISPLAYOBJECT->XResize=TRUE;
  152.       if(DISPLAYOBJECT->Flags&TROB_DISPLAYOBJECT_RETURNOK)
  153.         {
  154.           if((((struct TR_AppPrefs *)(data->project->trp_App->tra_Prefs))->flags)&TRPF_RETURNARROW)
  155.             DISPLAYOBJECT->MinWidth+=
  156.           (((data->project->trp_PropFont->tf_YSize/2)+
  157.         ((data->project->trp_PropFont->tf_YSize*16)/11))-2);
  158.           else DISPLAYOBJECT->MinWidth++;
  159.         }
  160.     }
  161.   else /* Image button */
  162.     {
  163.       DISPLAYOBJECT->MinHeight+=2;
  164.       DISPLAYOBJECT->MinWidth=DISPLAYOBJECT->MinHeight+3;
  165.     }
  166.  
  167.   return (ULONG)object;
  168. }
  169.  
  170.  
  171. TR_SIMPLEMETHOD(Button,DISPOSE)
  172. {
  173.   if(BUTTON->Type==TRBT_TEXT) if(BUTTON->Text) FreeVec((APTR)(BUTTON->Text));
  174.   return 1L;
  175. }
  176.  
  177.  
  178. TR_METHOD(Button,INSTALL,InstallData)
  179. {
  180.   struct Gadget *gadget;
  181.  
  182.   TRDP_DisplayObject_INSTALL(object,messageid,data,metaclass->trc_SuperClass);
  183.  
  184.   if(!(BUTTON->Image=(struct Image *)NewObject(BUTTON->BClass,NULL,
  185.                            IA_Height,      DISPLAYOBJECT->Height,
  186.                            IA_Width,       DISPLAYOBJECT->Width,
  187.                            SYSIA_DrawInfo, OBJECT->Project->trp_DrawInfo,
  188.                            TAG_END)))
  189.     return NULL;
  190.  
  191.   if(!(gadget=TR_CreateGadgetTags(
  192.                   OBJECT->Project,
  193.                   OBJECT,
  194.                   GENERIC_KIND,
  195.                   DISPLAYOBJECT->Left,
  196.                   DISPLAYOBJECT->Top,
  197.                   DISPLAYOBJECT->Width,
  198.                   DISPLAYOBJECT->Height,
  199.                   TAG_END)))
  200.     return NULL;
  201.  
  202.   BUTTON->Gadget=gadget;
  203.  
  204.   gadget->Flags |= GFLG_GADGIMAGE|GFLG_GADGHIMAGE;
  205.   gadget->GadgetType |= GTYP_BOOLGADGET;
  206.   gadget->Activation |= GACT_RELVERIFY;
  207.   gadget->GadgetRender = gadget->SelectRender = BUTTON->Image;
  208.   BUTTON->Image->ImageData=(USHORT *)object;
  209.   if(TR_DO_DISABLED) gadget->Flags |= GFLG_DISABLED;
  210.   return 1L;
  211. }
  212.  
  213.  
  214. TR_SIMPLEMETHOD(Button,REMOVE)
  215. {
  216.   if(BUTTON->Image) DisposeObject((Object *)(BUTTON->Image));
  217.   return TRDP_DisplayObject_REMOVE(object,messageid,data,metaclass->trc_SuperClass);
  218. }
  219.  
  220.  
  221. TR_METHOD(Button,SETATTRIBUTE,SetAttributeData)
  222. {
  223.   switch(data->attribute)
  224.     {
  225.     case 0:
  226.       BUTTON->Type=data->value;
  227.       return 1;
  228.  
  229.     case TRAT_Flags:
  230.       BUTTON->Flags=data->value;
  231.       if((BUTTON->Flags)&(TRBU_RETURNOK)) DISPLAYOBJECT->Flags|=TROB_DISPLAYOBJECT_RETURNOK;
  232.       if((BUTTON->Flags)&(TRBU_ESCOK)) DISPLAYOBJECT->Flags|=TROB_DISPLAYOBJECT_ESCOK;
  233.       if((BUTTON->Flags)&(TRBU_YRESIZE)) DISPLAYOBJECT->YResize=TRUE;
  234.       return 1;
  235.  
  236.     case TRAT_Text:
  237.       BUTTON->Text=(STRPTR)(data->value);
  238.       return 1;
  239.  
  240.     default:
  241.       return TRDP_DisplayObject_SETATTRIBUTE(object,messageid,data,metaclass->trc_SuperClass);
  242.     }
  243. }
  244.  
  245.  
  246. TR_METHOD(Button,KEYDOWN,EventData)
  247. {
  248.   if(!BUTTON->IsPressed)
  249.     {
  250.       if((data->imsg->Code)&&((BUTTON->Flags)&TRBU_UNSHIFTED)) return NULL;
  251.       if((!(data->imsg->Code))&&((BUTTON->Flags)&TRBU_SHIFTED)) return NULL;
  252.       TR_SelectGadget(OBJECT->Project, BUTTON->Gadget,TRUE);
  253.       BUTTON->IsPressed=TRUE;
  254.     }
  255.   return 1L;
  256. }
  257.  
  258.  
  259. TR_METHOD(Button,KEYCANCELLED_DISABLED_ENABLED,EventData)
  260. {
  261.   if(BUTTON->IsPressed)
  262.     {
  263.       TR_SelectGadget(OBJECT->Project, BUTTON->Gadget,FALSE);
  264.       BUTTON->IsPressed=FALSE;
  265.     }
  266.   if((messageid==TROM_DISABLED)||(messageid==TROM_ENABLED))
  267.     TR_DisableGadget(OBJECT->Project, BUTTON->Gadget, TR_DO_DISABLED);
  268.   return 1L;
  269. }
  270.  
  271.  
  272. TR_METHOD(Button,KEYUP,EventData)
  273. {
  274.   struct TR_Message *m;
  275.  
  276.   if(BUTTON->IsPressed) if(m=TR_CreateMsg(Self.DO.O.Project->trp_App))
  277.     {
  278.       m->trm_ID=DISPLAYOBJECT->ID;
  279.       m->trm_Class=TRMS_ACTION;
  280.     }
  281.  
  282.   return TR_DIRECTMETHODCALL(Button,KEYCANCELLED_DISABLED_ENABLED);
  283. }
  284.  
  285.  
  286. TR_METHOD(Button,EVENT,EventData)
  287. {
  288.   struct TR_Message *m;
  289.  
  290.   if((data->imsg->Class==IDCMP_GADGETUP)&&(data->imsg->IAddress==(APTR)(BUTTON->Gadget)))
  291.     if(m=TR_CreateMsg(Self.DO.O.Project->trp_App))
  292.       {
  293.     m->trm_ID=DISPLAYOBJECT->ID;
  294.     m->trm_Class=TRMS_ACTION;
  295.     return TROM_EVENT_SWALLOWED;
  296.       }
  297.   return TROM_EVENT_CONTINUE;
  298. }
  299.  
  300.  
  301. TR_SIMPLEMETHOD(Button,CREATECLASS)
  302. {
  303.   if(!(TRCL_BUTTON_BoopsiImage=TRCL_BUTTON_InitBoopsiImage())) return TRUE;
  304.   return FALSE;
  305. }
  306.  
  307.  
  308. TR_SIMPLEMETHOD(Button,DISPOSECLASS)
  309. {
  310.   if(TRCL_BUTTON_BoopsiImage) FreeClass(TRCL_BUTTON_BoopsiImage);
  311.   return NULL;
  312. }
  313.  
  314.  
  315. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  316. ////////////////////////////////////////////////////////////////////////////// BOOPSI image class 'BUTTON' //
  317. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  318.  
  319. ULONG    __asm TRCL_BUTTON_DispatchBoopsiImage(register __a0 struct IClass *Class, register __a2 Object *Object, register __a1 Msg ObjMsg)
  320. {
  321.   ULONG retval=TRUE;
  322.   struct Hook *hook=(struct Hook *)Class;
  323.   ULONG tempa4=__builtin_getreg(12);
  324.  
  325.   __builtin_putreg(12,(ULONG)hook->h_Data);
  326.  
  327.   if(ObjMsg->MethodID==IM_DRAW)
  328.     TRCL_BUTTON_DrawBoopsiImage((struct Image *)Object, (struct impDraw *)ObjMsg);
  329.   else
  330.     retval=DoSuperMethodA(Class, Object, ObjMsg);
  331.  
  332.   __builtin_putreg(12,tempa4);
  333.   return retval;
  334. }
  335.  
  336.  
  337. struct IClass __inline *TRCL_BUTTON_InitBoopsiImage(void)
  338. {
  339.   struct IClass *TRCL_BUTTON_BoopsiClass;
  340.  
  341.   if((TRCL_BUTTON_BoopsiClass = MakeClass(NULL, IMAGECLASS, NULL, 0, 0)))
  342.   {
  343.     TRCL_BUTTON_BoopsiClass->cl_Dispatcher.h_Entry = (HOOKFUNC)TRCL_BUTTON_DispatchBoopsiImage;
  344.     TRCL_BUTTON_BoopsiClass->cl_Dispatcher.h_Data  = (void *) __builtin_getreg(12);
  345.   }
  346.  
  347.   return TRCL_BUTTON_BoopsiClass;
  348. }
  349.  
  350.  
  351. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. /////////////////////////////////////////////////////////////////////////// BOOPSI image drawing functions //
  353. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354.  
  355. VOID __inline TR_DrawReturnArrowImage(struct RastPort *rp,ULONG l,ULONG t,ULONG w,ULONG h, ULONG shinepen, ULONG shadowpen)
  356. {
  357.   SetAPen(rp,shadowpen);
  358.   if(h<11)
  359.   {
  360.     t+=((h-8)/2);
  361.     Move(rp,l+3,t+6);
  362.     Draw(rp,l+1,t+4);
  363.     Draw(rp,l+3,t+2);
  364.     Move(rp,l+3,t+7);
  365.     Draw(rp,l,t+4);
  366.     Draw(rp,l+3,t+1);
  367.     Draw(rp,l+4,t+1);
  368.     Draw(rp,l+4,t+3);
  369.     Draw(rp,l+w-4,t+3);
  370.     Draw(rp,l+w-4,t);
  371.     Draw(rp,l+w-1,t);
  372.     SetAPen(rp,shinepen);
  373.     Move(rp,l+w-1,t+1);
  374.     Draw(rp,l+w-1,t+5);
  375.     Draw(rp,l+4,t+5);
  376.     Draw(rp,l+4,t+7);
  377.   }
  378.   else
  379.   {
  380.     Move(rp,l+((w*5)/16),t+h);
  381.     Draw(rp,l,t+((h*6)/11));
  382.     Draw(rp,l+((w*5)/16),t+(h/11));
  383.     Move(rp,l+1+((w*5)/16),t+h);
  384.     Draw(rp,l+1,t+((h*6)/11));
  385.     Draw(rp,l+1+((w*5)/16),t+(h/11));
  386.     Draw(rp,l+1+((w*5)/16),t+((h*4)/11));
  387.     Draw(rp,l+((w*11)/16),t+((h*4)/11));
  388.     Draw(rp,l+((w*11)/16),t);
  389.     Draw(rp,l+w,t);
  390.     SetAPen(rp,shinepen);
  391.     Move(rp,l+w,t+1);
  392.     Draw(rp,l+w,t+((h*8)/11));
  393.     Draw(rp,l+1+((w*5)/16),t+((h*8)/11));
  394.     Draw(rp,l+1+((w*5)/16),t+h);
  395.   }
  396. }
  397.  
  398.  
  399. void __inline TRCL_BUTTON_DrawBoopsiImage_BUTTON(struct RastPort *RPort,
  400.                          UWORD left, UWORD top, UWORD width, UWORD height,
  401.                          struct TROD_Button *object, struct TR_Project *project,
  402.                          BOOL selected, struct impDraw *DrawMsg)
  403. {
  404.   SetDrMd(RPort, JAM1);
  405.  
  406.   // Text
  407.   if(BUTTON->Text)
  408.   {
  409.     if(((((struct TR_AppPrefs *)(project->trp_App->tra_Prefs))->flags)&TRPF_RETURNARROW)&&(DISPLAYOBJECT->Flags&TROB_DISPLAYOBJECT_RETURNOK))
  410.     {
  411.       TR_InternalPrintText(project,RPort,BUTTON->Text,
  412.         left+((width-BUTTON->PixelTextLength-(((project->trp_PropFont->tf_YSize)*16)/11)-((project->trp_PropFont->tf_YSize)/2))/2), // left+project->trp_PropFont->tf_YSize,
  413.         top+((height-project->trp_PropFont->tf_YSize)/2),width /*dummy*/,
  414.         selected?TRTX_SELECTED:NULL);
  415.       TR_DrawReturnArrowImage(RPort,
  416.         left+BUTTON->PixelTextLength+((project->trp_PropFont->tf_YSize)/2)+((width-BUTTON->PixelTextLength-(((project->trp_PropFont->tf_YSize)*16)/11)-((project->trp_PropFont->tf_YSize)/2))/2), // left+1+width-(((project->trp_PropFont->tf_YSize)*16)/11)-(project->trp_PropFont->tf_YSize),
  417.         top+((height-project->trp_PropFont->tf_YSize)/2),
  418.         ((project->trp_PropFont->tf_YSize)*16)/11,
  419.         project->trp_PropFont->tf_YSize,
  420.         DrawMsg->imp_DrInfo->dri_Pens[SHINEPEN],
  421.         DrawMsg->imp_DrInfo->dri_Pens[SHADOWPEN]);
  422.     }
  423.     else
  424.     {
  425.       TR_InternalPrintText(project,RPort,BUTTON->Text,
  426.         left+((width-BUTTON->PixelTextLength)/2),
  427.         top+((height-project->trp_PropFont->tf_YSize)/2),width /*dummy*/,
  428.         ((DISPLAYOBJECT->Flags&TROB_DISPLAYOBJECT_RETURNOK)?
  429.      TRTX_BOLD:NULL)|(selected?TRTX_SELECTED:NULL));
  430.     }
  431.   }
  432. }
  433.  
  434.  
  435. void __inline TRCL_BUTTON_DrawBoopsiImage_GETFILE(struct RastPort *RPort,
  436.                           UWORD left, UWORD top, UWORD width, UWORD height,
  437.                           struct TROD_Button *object, struct TR_Project *project,
  438.                           BOOL selected, struct impDraw *DrawMsg)
  439. {
  440.   WORD i, FileArray[22]   = {0,-2, 6,-2, 6,2, 11,2, 11,7, 0,7, 0,-2, 6,-2, 11,2, 11,7, 0,7},
  441.        DeltaX, DeltaY, DeltaX2, DeltaY2;
  442.  
  443.   // Reposition vectors to new positions
  444.   for(i=0; i<11; i++)
  445.   {
  446.     FileArray[(i<<1)]+=(left+4);
  447.     FileArray[(i<<1)+1]+=(top+5);
  448.   }
  449.  
  450.   // Scale image
  451.   DeltaX=width-20;
  452.   DeltaY=height-16;
  453.   DeltaX2=DeltaX>>1;
  454.   DeltaY2=DeltaY>>1;
  455.   FileArray[2]+=DeltaX2;
  456.   FileArray[4]+=DeltaX2;
  457.   FileArray[6]+=DeltaX;
  458.   FileArray[8]+=DeltaX;
  459.   FileArray[14]+=DeltaX2;
  460.   FileArray[16]+=DeltaX;
  461.   FileArray[18]+=DeltaX;
  462.   FileArray[5]+=DeltaY2;
  463.   FileArray[7]+=DeltaY2;
  464.   FileArray[9]+=DeltaY;
  465.   FileArray[11]+=DeltaY;
  466.   FileArray[17]+=DeltaY2;
  467.   FileArray[19]+=DeltaY;
  468.   FileArray[21]+=DeltaY;
  469.  
  470.   // Draw image
  471.   SetAPen(RPort, DrawMsg->imp_DrInfo->dri_Pens[TEXTPEN]);
  472.   Move(RPort, left + 4, top + 5 + DeltaY2);
  473.   PolyDraw(RPort, 11, &FileArray[0]);
  474. }
  475.  
  476.  
  477. void __inline TRCL_BUTTON_DrawBoopsiImage_GETDRAWER(struct RastPort *RPort,
  478.                             UWORD left, UWORD top, UWORD width, UWORD height,
  479.                             struct TROD_Button *object, struct TR_Project *project,
  480.                             BOOL selected, struct impDraw *DrawMsg)
  481. {
  482.   WORD i, DrawerArray[28] = {0,7, 1,7, 1,0, 1,7, 11,7, 11,0, 9,-2, 6,-2, 3,0, 2,0, 2,1, 4,1, 6,2, 10,2},
  483.        DeltaX, DeltaY, DeltaX2, DeltaY2, DeltaY3;
  484.  
  485.   // Reposition vectors to new positions
  486.   for(i=0; i<14; i++)
  487.   {
  488.     DrawerArray[(i<<1)]+=(left+4);
  489.     DrawerArray[(i<<1)+1]+=(top+5);
  490.   }
  491.  
  492.   // Scale image
  493.   DeltaX=width-20;
  494.   DeltaY=height-16;
  495.   DeltaX2=DeltaX>>1;
  496.   DeltaY2=DeltaY>>1;
  497.   DeltaY3=DeltaY>>2;
  498.  
  499.   DrawerArray[8]+=DeltaX;
  500.   DrawerArray[10]+=DeltaX;
  501.   DrawerArray[12]+=DeltaX;
  502.   DrawerArray[26]+=DeltaX;
  503.   DrawerArray[14]+=DeltaX2;
  504.   DrawerArray[16]+=DeltaX2;
  505.   DrawerArray[22]+=DeltaX2;
  506.   DrawerArray[24]+=DeltaX2;
  507.   DrawerArray[1]+=DeltaY;
  508.   DrawerArray[3]+=DeltaY;
  509.   DrawerArray[7]+=DeltaY;
  510.   DrawerArray[9]+=DeltaY;
  511.   DrawerArray[5]+=DeltaY3;
  512.   DrawerArray[11]+=DeltaY3;
  513.   DrawerArray[17]+=DeltaY3;
  514.   DrawerArray[19]+=DeltaY3;
  515.   DrawerArray[21]+=DeltaY3;
  516.   DrawerArray[23]+=DeltaY3;
  517.   DrawerArray[25]+=DeltaY2;
  518.   DrawerArray[27]+=DeltaY2;
  519.  
  520.   // Draw image
  521.   SetAPen(RPort, DrawMsg->imp_DrInfo->dri_Pens[TEXTPEN]);
  522.   Move(RPort, left + 4, top + 5 + DeltaY3);
  523.   PolyDraw(RPort, 14, &DrawerArray[0]);
  524. }
  525.  
  526.  
  527. void __inline TRCL_BUTTON_DrawBoopsiImage_GETENTRY(struct RastPort *RPort,
  528.                            UWORD left, UWORD top, UWORD width, UWORD height,
  529.                            struct TROD_Button *object, struct TR_Project *project,
  530.                            BOOL selected, struct impDraw *DrawMsg)
  531. {
  532.   LONG PointWidth, Len, Foot, i;
  533.  
  534.   // Adjust image for wider borders
  535.   left+=(BUTTON->BorderHeight-1);
  536.   top+=(BUTTON->BorderHeight-1);
  537.   width-=2*(BUTTON->BorderHeight-1);
  538.   height-=2*(BUTTON->BorderHeight-1);
  539.  
  540.   // Picker
  541.  
  542.   SetAPen(RPort, DrawMsg->imp_DrInfo->dri_Pens[TEXTPEN]);
  543.  
  544.   left+=2;
  545.   top+=1;
  546.   width-=4;
  547.   height-=2;
  548.  
  549.   left+=(width+15)/16;
  550.   top+=(height+15)/16;
  551.  
  552.   width-=2*((width+15)/16);
  553.   height-=2*((height+15)/16);
  554.  
  555.   Foot=top+top+height-1;
  556.  
  557.   PointWidth=(width+1)/2;
  558.  
  559.   if(2*PointWidth>width) PointWidth--;
  560.  
  561.   if(PointWidth)
  562.   {
  563.     for(i=0; i<(height+31)/32; i++)
  564.     {
  565.       Move(RPort,left,Foot-(top+i));
  566.       Draw(RPort,left+width-1,Foot-(top+i));
  567.     }
  568.     top+=(height+15)/16;
  569.     for(i=0; i<(height+1)/2; i++)
  570.     {
  571.       if(Len=(PointWidth*(i+1))/((height+1)/2))
  572.       {
  573.         Move(RPort,left+PointWidth-Len,Foot-(top+i));
  574.         Draw(RPort,left+PointWidth+Len,Foot-(top+i));
  575.       }
  576.     }
  577.     if(Len=((width+3)/4)/2)
  578.     {
  579.       for(i=height/2; i<height-(height+15)/16; i++)
  580.       {
  581.         Move(RPort,left+PointWidth-Len,Foot-(top+i));
  582.         Draw(RPort,left+PointWidth+Len,Foot-(top+i));
  583.       }
  584.     }
  585.   }
  586. }
  587.  
  588.  
  589. void __inline TRCL_BUTTON_DrawBoopsiImage(struct Image *Image, struct impDraw *DrawMsg)
  590. {
  591.   struct TROD_Button *object = (struct TROD_Button *)(Image->ImageData);
  592.   struct RastPort *RPort = DrawMsg->imp_RPort;
  593.   UWORD left = Image ->LeftEdge + DrawMsg->imp_Offset.X, top = Image ->TopEdge + DrawMsg->imp_Offset.Y,
  594.         width = Image ->Width, height = Image ->Height;
  595.   struct TR_Project *project = OBJECT->Project;
  596.   BOOL s = (DrawMsg->imp_State==IDS_SELECTED);
  597.  
  598.   /* Background */
  599.   TR_InternalAreaFill(project, RPort, left, top, left+width-1, top+height-1, s?TRSI_SBUTTONBACK:TRSI_USBUTTONBACK);
  600.  
  601.   /* Border */
  602.   TR_InternalDrawFrame(project,RPort,left,top,width,height,TRFT_ABSTRACT_BUTTON,s?TRUE:FALSE);
  603.  
  604.   switch(BUTTON->Type)
  605.     {
  606.     case TRBT_GETFILE:
  607.       TRCL_BUTTON_DrawBoopsiImage_GETFILE(RPort,left,top,width,height,object,project,s,DrawMsg);
  608.       return;
  609.  
  610.     case TRBT_GETDRAWER:
  611.       TRCL_BUTTON_DrawBoopsiImage_GETDRAWER(RPort,left,top,width,height,object,project,s,DrawMsg);
  612.       return;
  613.  
  614.     case TRBT_GETENTRY:
  615.       TRCL_BUTTON_DrawBoopsiImage_GETENTRY(RPort,left,top,width,height,object,project,s,DrawMsg);
  616.       return;
  617.  
  618.     default:
  619.       TRCL_BUTTON_DrawBoopsiImage_BUTTON(RPort,left,top,width,height,object,project,s,DrawMsg);
  620.     }
  621. }
  622.